<?php

namespace JsonLowCode\Traits;


use JsonLowCode\Enum\ClassName;
use JsonLowCode\Support\Js;

trait BaseProps
{
    /**
     * 设置组件 key
     * @param string $key
     * @return $this
     */
    public function key(string $key): static
    {
        return $this->prop('key',$key);
    }

    /**
     * 设置prop属性id值
     * @param string|null $id
     * @return $this
     */
    public function id(string $id = null): static
    {
        return $this->prop('id',$id);
    }

    /**
     * 设置组件ref
     * @param string $ref
     * @return $this
     */
    public function ref(string $ref): static
    {
        return $this->prop('ref',$ref);
    }

    /**
     * 设置props属性
     * @param array $props
     * @return $this
     */
    public function props(array $props): static
    {
        $prevProps = $this->getProps();
        $props = array_merge($prevProps, $props);
        return $this->setAttribute("props",$props);
    }

    /**
     * 设置组件props属性值
     * @param string $key 属性key
     * @param mixed $value 属性值value
     * @return $this
     */
    public function prop(string $key, mixed $value): static
    {
        $props = $this->getProps();
        $props[$key] = $value;
        return $this->setAttribute("props",$props);
    }

    /**
     * 获取所有props
     * @return mixed
     */
    public function getProps(): array
    {
        return $this->getAttribute("props")?:[];
    }

    /**
     * @param string $prop
     * @return mixed
     */
    public function getProp(string $prop): mixed
    {
        $props = $this->getProps();
        return $props[$prop]??null;
    }

    /**
     * 删除某个属性
     * @param string $key
     * @return $this
     */
    public function removeProp(string $key): static
    {
        $props = $this->getProps();
        if (isset($props[$key])) unset($props[$key]);
        return $this->setAttribute("props",$props);
    }

    /**
     * 获取ref值
     * @return string
     */
    public function getRef(): string
    {
        return (string)$this->getProp("ref");
    }

    /**
     * 设置组件props属性 JSFunction 函数绑定
     * @param string $prop 属性key
     * @param string $value 属性值value
     * @return $this
     */
    public function vFunc(string $prop, string $value): static
    {
        return $this->prop($prop,JSFunction($value));
    }

    /**
     * 设置组件props属性 JSExpression 表达式绑定
     * @param string $prop 属性key
     * @param string $value 属性值value 变量 this.a,this.a.b,this.a.b.c
     * @param array $extends 扩展值
     * @return $this
     */
    public function vBind(string $prop, string $value, array $extends = []): static
    {
        return $this->prop($prop, JSExpression($value, $extends));
    }

    /**
     * 计算属性
     * @param string $prop
     * @param string $value
     * @return $this
     */
    public function computed(string $prop,string $value): static
    {
        return $this->vBind($prop, $value, ['computed'=>true]);
    }

    /**
     * 设置组件props的event事件
     * @param string $key 属性key
     * @param mixed $value 属性值value
     * @param bool $isJSExpression 是否js表达式
     * @param array $extends 扩展值
     * @return $this
     */
    public function vOn(string $key, mixed $value, bool $isJSExpression = false, array $extends = []): static
    {
        if ($isJSExpression){
            return $this->vBind($key, $value, $extends);
        }else{
            return $this->vFunc($key, $value);
        }
    }


    /**
     * 设置组件class样式类名
     * @param string|string[] $class
     * @return $this
     */
    public function class(string|array $class): static
    {
        $props = $this->getAttribute("props")?:[];
        $oldClass = $props['className']??[];
        $classList = array_merge($oldClass, is_array($class)?$class:[$class]);
        $this->prop('className',implode(" ",$classList));
        return $this;
    }

    /**
     * 清除class
     * @param string|null $className
     * @return $this
     */
    public function clearClass(string $className = null): static
    {
        $props = $this->getProps();
        if (isset($props['className'])){
            if ($className){
                $class = str_replace($className,"",$props['class']);
                $props['className'] = $class;
            }else{
                unset($props['className']);
            }
            $this->setAttribute("props",$props);
        }
        return $this;
    }


    /**
     * 设置组件style样式
     * @param string $style
     * @return $this
     */
    public function style(string $style): static
    {
        return $this->prop("style",$style);
    }

    /**
     * 清除style样式
     * @return $this
     */
    public function clearStyle(): static
    {
        $props = $this->getProps();
        if (isset($props['style'])){
            unset($props['style']);
            $this->setAttribute("props",$props);
        }
        return $this;
    }

}
